import { HttpResponse, IHttpResponse, RuntimeError } from '@ibiz-template/core';
import { IDataEntity, Method } from '@ibiz-template/runtime';
import { IAppDEAction } from '@ibiz/model-core';

/**
 * 实体行为方法插件
 *
 * @author chitanda
 * @date 2022-10-10 12:10:37
 * @export
 * @class DEActionMethodPlugin
 * @extends {Method}
 */
export class DEActionMethodPlugin extends Method {
  declare method: IAppDEAction;

  async exec(
    context: IContext,
    data?: IData | IData[],
    params?: IParams,
  ): Promise<HttpResponse<IData>> {
    let result: IHttpResponse<IData>;
    switch (this.method.codeName) {
      case 'Create':
        result = await this.create(context, data!, params || {});
        break;
      case 'Get':
        result = await this.get(context, params);
        break;
      case 'GetDraft':
        result = await this.getDraft(context, params);
        break;
      case 'Remove':
        result = await this.remove(context, params);
        break;
      case 'Update':
        result = await this.update(context, data!, params);
        break;
      default:
        result = await this.getDraft(context, params);
        break;
    }

    return result;
  }

  /**
   * 创建数据
   *
   * @author chitanda
   * @date 2022-08-24 20:08:01
   * @param {IContext} context
   * @param {IData} data
   * @return {*}  {Promise<IHttpResponse<IData>>}
   */
  async create(
    context: IContext,
    data?: IData | IData[],
    params?: IParams,
  ): Promise<IHttpResponse<IDataEntity>> {
    if (!data) {
      throw new RuntimeError('create行为没有传data');
    }
    const path = this.calcPath(context);
    const res = await this.app.net.post(path, data, params);
    res.data = await this.result.handle(context, res.data);
    return res as IHttpResponse<IDataEntity>;
  }

  /**
   * 删除数据
   *
   * @author chitanda
   * @date 2022-08-24 20:08:56
   * @param {IContext} context
   * @param {IParams} [params]
   * @return {*}  {Promise<IHttpResponse<IDataEntity>>}
   */
  async remove(
    context: IContext,
    params?: IParams,
  ): Promise<IHttpResponse<IDataEntity>> {
    const path = this.calcPath(context);
    const res = await this.app.net.delete(
      `${path}/${context[this.entity.codeName!.toLowerCase()]}`,
      params,
    );
    return res as IHttpResponse<IDataEntity>;
  }

  /**
   * 更新数据
   *
   * @author chitanda
   * @date 2022-09-13 19:09:39
   * @param {IContext} context
   * @param {(IData | IDataEntity)} data
   * @param {IParams} [params={}]
   * @return {*}  {Promise<IHttpResponse<IDataEntity>>}
   */
  async update(
    context: IContext,
    data?: IData | IData[],
    params?: IParams,
  ): Promise<IHttpResponse<IDataEntity>> {
    if (!data) {
      throw new RuntimeError('update行为没有传data');
    }
    const path = this.calcPath(context);
    const res = await this.app.net.put(
      `${path}/${context[this.entity.codeName!.toLowerCase()]}`,
      data,
      params,
    );
    res.data = await this.result.handle(context, res.data);
    return res as IHttpResponse<IDataEntity>;
  }

  /**
   * 获取数据
   *
   * @author chitanda
   * @date 2022-08-24 20:08:07
   * @param {IContext} context
   * @param {IParams} [params]
   * @return {*}  {Promise<IHttpResponse<IDataEntity>>}
   */
  async get(
    context: IContext,
    params: IParams = {},
  ): Promise<IHttpResponse<IDataEntity>> {
    const path = this.calcPath(context);
    const res = await this.app.net.get(
      `${path}/${context[this.entity.codeName!.toLowerCase()]}`,
      params,
    );
    res.data = await this.result.handle(context, res.data);
    return res as IHttpResponse<IDataEntity>;
  }

  /**
   * 获取默认数据
   *
   * @author chitanda
   * @date 2022-08-24 20:08:26
   * @param {IContext} context
   * @param {IParams} [params]
   * @return {*}  {Promise<IHttpResponse<IData>>}
   */
  async getDraft(
    context: IContext,
    params?: IParams,
  ): Promise<IHttpResponse<IData>> {
    ibiz.message.success('实体行为插件调用成功！');
    const path = this.calcPath(context);
    const res = await this.app.net.get(`${path}/getdraft`, params);
    res.data = await this.result.handle(context, res.data);
    return res;
  }
}
